home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Orlando_1993 / Devcon93.4 / Notes / DevCon-93 < prev    next >
Encoding:
Text File  |  1993-01-08  |  20.9 KB  |  448 lines

  1. Advanced EXEC and CPU Issues
  2.  
  3. As we have seen, the pace of technology changes are getting faster all the
  4. time.  It is hoped that the Amiga and its applications will be able to keep
  5. up with these changes as best as possible.  This however means that changes
  6. will need to take place in both the Amiga's OS and in application software.
  7.  
  8. With the release of V37 and V39 EXEC, a number of new concepts have been
  9. advanced to a stage from which a number of new technologies can be lauched.
  10. In fact, a number of the functions in V37 EXEC are required in order to make
  11. the system work with 68040 CPUs in a consistant manner.  (Namely the
  12. CacheControl(), CachePreDMA(), CachePostDMA(), CacheClearU(), and
  13. CacheClearE() calls)  With V39, the addition of private memory pools and the
  14. clean up of the memory allocation routines has set the ground work for some
  15. more advanced memory systems.
  16.  
  17. New for V39
  18.  
  19. For V39, I had some time to clean up some of the areas of EXEC that could
  20. not be fixed in some external manner.  The major changes were in the
  21. semaphores, memory subsystems, and the ROM debugger.
  22.  
  23. Semaphores are the key to making a multitasking system work as one system.
  24. EXEC has a very nice set of semaphore functions that are called
  25. SignalSemaphores.  Before V39, these semaphores could only be used and
  26. accessed in a synchronous manner.  That is, you made a function call
  27. that would block until you had obtained the semaphore.  While this usually
  28. ends up being enough for most people, there are times when software may
  29. need to "bid" for a semaphore and go and do something until it obtains it.
  30. EXEC already had this concept in the Procure() and Vacate() functions but
  31. these functions were both broken and somewhat useless due to the fact that
  32. they worked with a different semaphore structure than the SignalSemaphores.
  33. As it turns out, I was able to reuse these two function calls and they
  34. now, when used with SignalSemaphores, work and are useful in that the
  35. same semaphore may be both synchronously and asyncronously obtained.
  36. See the AutoDocs on Procure() and Vacate() for more information as to
  37. how this works.
  38.  
  39. One of the features of the Amiga has always been the dynamic nature of its
  40. use of memory.  This has also been one of the trickiest parts of good Amiga
  41. programming.  Applications would like to dynamically use memory and release
  42. it but with more than one running at the same time, memory got fragmented
  43. and performance suffered.  For V39, two different parts were added to the
  44. memory subsystem; pools and memory handlers.
  45.  
  46. Memory pools are a way to help combat memory fragmentation, increase the
  47. speed of the system, and give a simple way to keep associated memory
  48. together.  Due to the fact that memory pools are "private" to the
  49. application, a number of performance benefits are obtained (including not
  50. neededing to go into Forbid() during allocation or deallocation from the
  51. pool).  Since pools give the system a simple way to keep your allocations
  52. together it also gives the system a simple way to release your allocations
  53. by just destrying the pool as a whole.  Also, the design was left back-box
  54. such that future system enhancements can be made to them without too many
  55. problems.  (A very important point here is that pools will be the memory
  56. interface of choice in the future.)  For more information on the memory
  57. pools, see the AutoDocs and the next AmigaMail.
  58.  
  59. Memory handlers are an extension to the Amiga's physical memory manegment
  60. system.  As you know, when a memory allocation fails, the system will
  61. first attempt to release any resources that are no longer in use and retry
  62. the allocation before it will truely fail the allocation.  This design
  63. was very inovative when the Amiga first came out but it was not complete
  64. enough to let applications cache data as long as there was enough memory
  65. or to do other, more complex memory usage games.  The memory handler system
  66. expands this feature and makes a number of performance problems much easier
  67. to deal with.  (Such as resterized outline font caching or large database
  68. RAM caching).  It also makes it possible for the caching code to know how
  69. much and of what type of memory the currently failing allocation is for such
  70. that it can more intelligently release memory without releasing everything.
  71. The following is a quick overview of the design goals behind the memory
  72. handler design.  As a side benefit to this work, most memory allocations are
  73. over 100 cycles faster on a 68000 based machine since the overhead of RAMLIB's
  74. SetFunction() of AllocMem() is no longer an issue.
  75.  
  76.     ------------
  77.  
  78.     Memory Handler - Quick Overview
  79.  
  80.     The basic design is a handler list that is called when a memory
  81.     allocation fails.  The handler list (just like input.device, etc) will
  82.     contain routines that applicationss and libraries added.
  83.  
  84.     Each handler in the list will be called in order until the memory
  85.     allocation works or the handler list is completed.  Only after the
  86.     handler list has been completely traversed will the allocation fail.
  87.  
  88.     The handler list is a standard exec-style list that is stored in
  89.     priority order.
  90.  
  91.     RAMLIB, which currently SetFunctions the AllocMem() routine will no
  92.     longer do this but rather add itself to the handler list at priority 0.
  93.     This lets applications come before and after the RAMLIB expunge.
  94.  
  95.     -------------
  96.  
  97.     New functions:
  98.  
  99.     There will need to be two new functions in EXEC to deal with the
  100.     handler list.  There will also be a new flag to AllocMem()
  101.  
  102.     The basic functions are:
  103.  
  104.     void AddMemHandler(struct Interrupt *)
  105.                        a1
  106.  
  107.     void RemMemHandler(struct Interrupt *)
  108.                        a1
  109.  
  110.     AddMemHandler() - This function will take the handler given and enqueue
  111.     it onto the memory handler list.  Once on the list, the handler must be
  112.     ready to be called.  This means that the handler must be ready to be
  113.     called before this function even returns.
  114.  
  115.     RemMemHandler() - This function will remove the handler from the list.
  116.     This function *CAN* be called while within the handler.
  117.  
  118.     A new memory flag, MEMF_NO_EXPUNGE, will be added to exec. This flag
  119.     will cause the memory allocation attempt to fail without going through
  120.     the memory handler.  This is usefull for caching systems that may not
  121.     really need the memory but will take it if available and also is
  122.     required for use within the handler such that memory could be allocated
  123.     during the expunge cycle.  (Or at least attempted)  This flag will be
  124.     ignored in systems where there is no memory handler.
  125.  
  126.         BITDEF  MEM,NO_EXPUNGE,31    ;AllocMem: Do not call expunge on failure
  127.  
  128.     ------------
  129.  
  130.     The MemHandler structure:
  131.  
  132.     This structure is the data passed to a MemHandler.  This structure
  133.     is *READ ONLY*
  134.  
  135.     struct MemHandlerData
  136.     {
  137.         ULONG    memh_RequestSize;    /* Size of the requested allocation */
  138.         ULONG    memh_RequestFlags;    /* Flags of the requested allocation */
  139.         ULONG    memh_Flags;        /* Flags (see below) */
  140.     };
  141.  
  142.     The memh_RequestSize and memh_RequestFlags are the size and flags
  143.     arguments from the AllocMem() call that failed.
  144.  
  145.         BITDEF    MEMH,RECYCLE,0    ; Recycle
  146.  
  147.     The MEMHF_RECYCLE flag is 0 if this was the first time this handler was
  148.     called due to this allocation failure.  If this is 1, the handler
  149.     is being called again for the same failure.  See below about handler
  150.     return and recycling...
  151.  
  152.     ------------
  153.  
  154.     The Handler:
  155.  
  156.     The protocal for a MemHandler must be strictly followed.  Due to the
  157.     fact that the handlers are being called on the AllocMem() context and
  158.     the fact that AllocMem() *MUST* *NOT* break a Forbid(), the handler
  159.     *MUST* *NOT* break a Forbid().  Another issue is stack usage.  The
  160.     handler could be running on any task in the system that calls
  161.     AllocMem()  For this reason, the handler must try to keep stack usage
  162.     as low as possible.  Exact stack usage is not available, but a good
  163.     rule would be to keep it under 128 bytes if possible.
  164.  
  165.     The handler may call AllocMem() with the new MEMF_NO_EXPUNGE flag.
  166.     This flag is new to the exec that has the memory handler system.
  167.     Library expunge vectors can *not* make use of this feature. This flag
  168.     would let a handler move memory from one location to another.  For example,
  169.     if the requested memory is for CHIP, the handler could move any of its
  170.     CHIP allocations that it can to FAST memory (if possible) and would then
  171.     be able to help satisfy the MEMF_CHIP request.  Also caching systems may
  172.     wish to only cache an item if memory is available and would not want to
  173.     have the system do an expunge just to cache this "unimportant" item.
  174.  
  175.     The handler will be called in a Forbid() state that *MUST* *NOT* be
  176.     broken.
  177.  
  178.     A handler can RemMemHandler() itself *ONLY* if it
  179.     returns MEM_DID_NOTHING or MEM_ALL_DONE.
  180.  
  181.     The handler code, with is in (*is_Code)() of the interrupt structure
  182.     will be called as follows:
  183.  
  184.     a0=Pointer to (struct MemHandler)
  185.     a1=Value from is_Data
  186.     a2=Pointer to the Interrupt structure for this handler
  187.     a6=ExecBase
  188.  
  189.     The handler must follow the standard rules about register usage. Only
  190.     d0, d1, a0, and a1 may be modified, all other registers *MUST* remain
  191.     unchanged.
  192.  
  193.     Return results:
  194.  
  195.     d0=        MEM_DID_NOTHING
  196.         or    MEM_ALL_DONE
  197.         or    MEM_TRY_AGAIN
  198.  
  199.     MEM_DID_NOTHING    If the handler could not release any resources
  200.             it should return with d0 set to this.
  201.  
  202.     MEM_ALL_DONE    If the handler released all of its resources, it
  203.             should return this in d0.
  204.  
  205.     MEM_TRY_AGAIN    If the handler released some resources in hopes
  206.             that it will have solved the memory problem
  207.             it can return with this value.  In that case,
  208.             EXEC will retry the allocation and if it does not
  209.             work, will call the handler again.  Note that
  210.             the handler can tell if it was already called by
  211.             the MEMHF_FIRST_TIME flag which will be 0 if this
  212.             is the first call to the handler.
  213.             The main use of this return value is to help
  214.             implement the RAMLIB handler but it could be usefull
  215.             for LRU caching code or caching code that
  216.             tries to defragment memory during expunge in order
  217.             to try to satisfy the allocation request.
  218.  
  219.     -------------
  220.  
  221.     RAMLIB:
  222.  
  223.     RAMLIB will, under this system, no longer setfunction the memory
  224.     allocation routines but rather add a memory handler at priority 0.
  225.     This handler would then be called when the allocation failed and RAMLIB
  226.     could then call the library expunge vectors as it does today.  If
  227.     RAMLIB wishes to continue to do the 2.0 partial expunge, that would be
  228.     possible with the MEM_TRY_AGAIN return value.
  229.  
  230.     -------------
  231.  
  232. Another key point in the design of V39 EXEC was to provide for a low-level
  233. debugging core that can be used to debug rather complex problems.  This
  234. low-level debugger, the Simple Amiga Debugging kernel, SAD, replaces ROM-WACK
  235. from pre-V39 systems.  One of the goals of SAD was to provide near emulator
  236. level access to debugging the Amiga.  Due to some minor hardware issues,
  237. this was not 100% implemented.  The goal was to use the unused NMI interrupt
  238. to trap into the SAD kernel and then let have the controlling systems
  239. talk to SAD and do whatever is needed of them.  By default, due to hardware
  240. issues on certain Amiga models, SAD in not connected to the NMI vector.  It
  241. is ready to be connected, but it is not.
  242.  
  243. The Simple Amiga Debugging Kernel (SAD) is a set of very simple control
  244. routines stored in the Kickstart ROM that would let debuggers control the
  245. Amiga's development enviroment from the outside.  These tools would make
  246. it possible to do remote machine development/debugging via just the
  247. on-board serial port.
  248.  
  249. This set of control routines is very simple and yet completely flexible,
  250. thus making it possible to control the whole machine.
  251.  
  252. Technical Issues
  253.  
  254. SAD will make use of the motherboard serial port that exists in all
  255. Amiga systems.  The connection via the serial port lets the system be
  256. able to execute SAD without needing any of the system software up and
  257. running. (SAD will play with the serial port directly)
  258.  
  259. With some minor changes to the Amiga hardware, an NMI-like line could
  260. be hooked up to a pin on the serial port.  This would let external
  261. control of the machine and would let the external controller stop the
  262. machine no matter what state it is in.  (NMI is that way)
  263.  
  264. In order to function correctly, SAD requires the some of the EXEC
  265. CPU control functions work and that ExecBase be valid.  Beyond that,
  266. SAD does not require the OS to be running.
  267.  
  268.  
  269. Command Overview
  270.  
  271. The basic commands needed to operate SAD are as follows:
  272.  
  273. Read and Write memory as byte, word, and longword.
  274. Get the register frame address (contains all registers)
  275. JSR to Address
  276. Return to system operation  (return from interrupt)
  277.  
  278. These basic routines will let the system do whatever is needed.
  279. Since the JSR to address and memory read/write routines can be used
  280. to download small sections of code that could be used to do more
  281. complex things, this basic command set is thus flexible enough
  282. to even replace itself.
  283.  
  284. Caches will automatically be flushed as needed after each write.
  285. (A call to CacheClearU() will be made after the write and before
  286. the command done sequence)
  287.  
  288. Technical Command Descriptions
  289.  
  290. Since the communications with SAD is via a serial port, data formats
  291. have been defined for minimum overhead while still giving reasonable data
  292. reliability.  SAD will use the serial port at default 9600 baud but the
  293. external tools can change the serial port's data rate if it wishes.  It
  294. would need to make sure that it will be able to reconnect.  SAD sets
  295. the baud rate to 9600 each time it is entered.  However, while within
  296. SAD, a simple command to write a WORD to the SERPER register would
  297. change the baud rate.  This will remain in effect until you exit and
  298. re-enter SAD or until you change the register again.  (This can be usefull
  299. if you need to transfer a large amount of data)
  300.  
  301. All commands have a basic format that they will follow.  All commands have
  302. both an ACK and a completion message.
  303.  
  304. Basic command format is:
  305.  
  306. SENDER:    $AF <command byte> [<data bytes as needed by command>]
  307.  
  308. Receive:
  309. Command ACK:  $00 <command byte>
  310.  
  311. Command Done: $1F <command byte> [<data if needed>]
  312.  
  313. Waiting: $53 $41 $44 $BF
  314.  
  315. Waiting when called from Debug():    $53 $41 $44 $3F
  316.  
  317. Waiting when in dead-end crash:     $53 $41 $44 $21
  318.  
  319. The data sequence will be that SAD will emit a $BF and then wait for a
  320. command. If no command is received within <2> seconds, it will emit $BF
  321. again and loop back.  (This is the "heart beat" of SAD)  When called from
  322. Debug() and not the NMI hook, SAD will use $3F as the "heart beat"
  323.  
  324. If SAD does not get a responce after <10> heartbeats, it will return to
  325. the system.  (Execute an RTS or RTE as needed)  This is to prevent a full
  326. hang.  The debugger at the other end can keep SAD happy by sending a
  327. NO-OP command.
  328.  
  329. All I/O in SAD times out.  During the transmition of a command, if
  330. more than 2 seconds pass between bytes of data SAD will time out
  331. and return to the prompt.  This is mainly to help make sure that
  332. SAD can never get into an i-loop situation.
  333.  
  334. Data Structure Issues
  335.  
  336. While executing in SAD, you may have full access to machine from the CPU
  337. standpoint.  However, this could also be a problem.  It is important to
  338. understand that when entered via NMI that many system lists may be in
  339. unstable state.  (NMI can happen in the middle of the AllocMem routine
  340. or task switch, etc)
  341.  
  342. Also, since you are doing debugging, it is up to you to determin what
  343. operations can be done and what can not be done.  A good example is
  344. that if you want to write a WORD or LONG that the address will need to
  345. be even on 68000 processors.  Also, if you read or write memory that does
  346. not exist, you may get a bus error.  Following system structures may
  347. require that you check the pointers at each step.
  348.  
  349. When entered via Debug(), you are now running as a "task" so you will
  350. be able to assume some things about system structures.  This means that
  351. you are not in supervisor state and that you can assume that the
  352. system is at least not between states.  However, remember that since
  353. you are debugging the system, some bad code could cause data structures
  354. to be invalid.  Again, standard debugging issues are in play.  SAD just
  355. gives you the hooks to do whatever you need.
  356.  
  357. Note:  When SAD prompts with $BF you will be in full disable/forbid
  358. state.  When $3F prompting, SAD will only do a Forbid().  It is possible
  359. for you to then disable interrupts as needed.  This is done such that it
  360. is possible to "run" the system from SAD when called with Debug().
  361.  
  362. Data Frames and the Registers
  363.  
  364. SAD generates a special data frame that can be used to read what
  365. registers contain and to change the contents of the registers.
  366. See the entry for GET_CONTEXT_FRAME for more details
  367.  
  368. For more information on how SAD works, please check the EXEC AutoDocs.
  369.  
  370.  
  371. The Future
  372.  
  373. Now that I have talked about the major changes to EXEC for V39, we should
  374. look into what the future may bring.  What follows is a general description
  375. of the "vision" I have for the EXEC of the future.  They do not mean that
  376. exactly these features or that all or only these features will be
  377. implemented.  However, it does show you some of the directions that we hope
  378. to be able to push the operating system.
  379.  
  380. One of the future features that is already somewhat in use is CPU-specific
  381. support libraries.  Currently, there is a 68040.library which patches itself
  382. into EXEC and the system to provide the functions needed to make the 68040
  383. based Amiga work.  Future processors will also need such support libraries.
  384. As such, a goal will be to have a different library for each of the processor
  385. groups.  This library would take care of things like handling of the various
  386. processor specific issues such as instruction emulation, cache control,
  387. MMU support, and other things that are system-level and CPU specific.
  388. (In other words, there will be a 68060.library and maybe even a 68030.library)
  389.  
  390. Along with the CPU-based extentions, the much asked for and very much
  391. mis-understood feature of virtual memory would become an issue.  The design
  392. (from the concept point of view) is rather far along at this point in time
  393. and now a number of changes to the memory system will make this possible.
  394. In order to prevent compatibility problems and other issues, the only way
  395. to obtain vertual memory would be to obtain a private pool with the
  396. attribute of PAGED memory.  As a side issue, since it is only via private
  397. pools that such memory can be allocated, it may be possible to have
  398. a form of protected pools too.
  399.  
  400. Object oriented programming has become a major "key" word in the market
  401. today.  While much of the OOP hype is just that, there are a number of
  402. benefits that can be had in a system that supports object oriented features.
  403. The benefits however, are only available if there is a good base from
  404. which the objects are built and includes the core functions that makes up
  405. the basic OOP interfaces.
  406.  
  407. For 2.0, Jim Mackraz implemented an object oriented gadget/image system
  408. for Intuition.  Basic Object Oriented Programming System for Intuition
  409. or BOOPSI as we call it, was a very important improvement in the dealing
  410. with the details of user interface building and operation.  The model was
  411. designed with those specific goals in mind and it added a great deal to
  412. the capability of Intuition and the user interfaces that can be built in
  413. Intuition.
  414.  
  415. One need, however, is for objects that may not be user interface based or
  416. have any need for those aspects.  Example objects would be a data retrieval
  417. object or maybe a network link object or even a "thread" object.  In fact,
  418. given the correct core set of objects, a full resource tracking system
  419. can be built out of just having objects dispose of their parts when the
  420. "process" or "task" object is disposed.
  421.  
  422. The object support that I envision would be very low overhead support for
  423. runtime "linked" objects.  (Much like shared code libraries are runtime
  424. "linked")  It would provide for both high-speed method inharitance and
  425. complex multiple inharitance.  Disk loaded object classes and application
  426. embedded private object classes would both be supported.
  427.  
  428. In addition, the long-awaited task-tree (child-tasking) support is once
  429. again on the list of things to do.  This would give tasks the ability to be
  430. notified about their children tasks (or parent task).  Some of this may
  431. be well suited to the object-based "task" or "thread" construct.
  432.  
  433. Debugging support will also continue to get better.  Both via tools such
  434. as Enforcer and via better support within the new constructs to check for
  435. and report invalid operations.  The hardest part of the developing a major
  436. application is the varification of its quality.  The system should be
  437. able to help here.
  438.  
  439. Conclusion
  440.  
  441. So, while much work needs to be done just to keep up with other aspects of
  442. the Amiga OS and the hardware (including new CPUs) there are a number of
  443. key issues/features that would make for an even better system.  Some of
  444. these are good because they are great "PR" (everyone talks about getting
  445. VM, even the 1-floppy A1200 owner who does not even have a MMU) and others
  446. are just very useful for system construction and simplified application
  447. development.  (Debugging software on such a complex system can be a pain)
  448.